package com.lyl.syt.service.impl;/**
 * @author Mr.Luo
 * @date 2022-05-26 15:21
 */

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyl.syt.common.exception.YyghException;
import com.lyl.syt.common.result.ResultCodeEnum;
import com.lyl.syt.dao.PaymentInfoDao;
import com.lyl.syt.enums.OrderStatusEnum;
import com.lyl.syt.enums.PaymentStatusEnum;
import com.lyl.syt.model.order.OrderInfo;
import com.lyl.syt.model.order.PaymentInfo;
import com.lyl.syt.service.OrderService;
import com.lyl.syt.service.PaymentInfoService;
import lombok.RequiredArgsConstructor;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * @author Mr.Luo
 * @date 2022-05-26 15:21
 * @desc
 */
@Service
@RequiredArgsConstructor
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoDao, PaymentInfo> implements PaymentInfoService {
    private final OrderService orderService;
    @Override
    public void savePaymentInfo(OrderInfo orderInfo, Integer paymentType) {
        //如果存在交易记录，直接返回
        if(existPaymentInfo(orderInfo, paymentType)){
            return;
        }
        // 保存交易记录
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setCreateTime(new Date());
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setPaymentType(paymentType);
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setPaymentStatus(PaymentStatusEnum.UNPAID.getStatus());
        String subject = new DateTime(orderInfo.getReserveDate()).toString("yyyy-MM-dd")+"|"+orderInfo.getHosname()+"|"+orderInfo.getDepname()+"|"+orderInfo.getTitle();
        paymentInfo.setSubject(subject);
        paymentInfo.setTotalAmount(orderInfo.getAmount());
        save(paymentInfo);
    }

    @Override
    public void paySuccess(String out_trade_no, Integer payType, Map<String, String> paramMap) {
        PaymentInfo paymentInfo = this.getPaymentInfo(out_trade_no, payType);
        if (null == paymentInfo) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        if (!paymentInfo.getPaymentStatus().equals(PaymentStatusEnum.UNPAID.getStatus())) {
            return;
        }
        //修改支付状态
        PaymentInfo paymentInfoUpd = new PaymentInfo();
        paymentInfoUpd.setPaymentStatus(PaymentStatusEnum.PAID.getStatus());
        paymentInfoUpd.setTradeNo(paramMap.get("transaction_id"));
        paymentInfoUpd.setCallbackTime(new Date());
        paymentInfoUpd.setCallbackContent(paramMap.toString());
        this.updatePaymentInfo(out_trade_no, paymentInfoUpd);
        //修改订单状态
        OrderInfo orderInfo = orderService.getById(paymentInfo.getOrderId());
        orderInfo.setOrderStatus(OrderStatusEnum.PAID.getStatus());
        orderService.updateById(orderInfo);
        // 调用医院接口，通知更新支付状态
    }

    @Override
    public PaymentInfo getPaymentInfo(Long orderId, Integer paymentType) {
        return lambdaQuery().eq(PaymentInfo::getOrderId, orderId)
                .eq(PaymentInfo::getPaymentType, paymentType)
                .one();
    }

    /**
     * 获取支付记录
     */
    private PaymentInfo getPaymentInfo(String outTradeNo, Integer paymentType) {
        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("out_trade_no", outTradeNo);
        queryWrapper.eq("payment_type", paymentType);
        return baseMapper.selectOne(queryWrapper);
    }

    /**
     * 更改支付记录
     */
    private void updatePaymentInfo(String outTradeNo, PaymentInfo paymentInfoUpd) {
        QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("out_trade_no", outTradeNo);
        baseMapper.update(paymentInfoUpd, queryWrapper);
    }



    /**
     * 判断是否存在交易就
     * @param orderInfo 订单信息
     * @param status 支付类型
     * @return true/false
     */
    private boolean existPaymentInfo(OrderInfo orderInfo, Integer status) {
        return lambdaQuery().eq(PaymentInfo::getOrderId, orderInfo.getId())
                .eq(PaymentInfo::getPaymentType, status)
                .exists();
    }
}
